package com.atguigu.tingshu.album.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.atguigu.tingshu.album.manager.VodManager;
import com.atguigu.tingshu.album.mapper.*;
import com.atguigu.tingshu.album.service.AlbumInfoService;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.common.kafka.constant.KafkaConst;
import com.atguigu.tingshu.common.kafka.service.KafkaService;
import com.atguigu.tingshu.common.result.ResultCodeEnum;
import com.atguigu.tingshu.common.util.AuthContextHolder;
import com.atguigu.tingshu.common.utils.ThrowUtil;
import com.atguigu.tingshu.dto.AlbumSaveOrUpdateDTO;
import com.atguigu.tingshu.enums.AlbumStatType;
import com.atguigu.tingshu.model.album.AlbumAttributeValue;
import com.atguigu.tingshu.model.album.AlbumInfo;
import com.atguigu.tingshu.query.album.AlbumInfoQuery;
import com.atguigu.tingshu.vo.album.AlbumAttributeValueVo;
import com.atguigu.tingshu.vo.album.AlbumInfoVo;
import com.atguigu.tingshu.vo.album.AlbumListVo;
import com.atguigu.tingshu.vo.album.AlbumStatVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

@Slf4j
@Service
@SuppressWarnings({ "all" })
public class AlbumInfoServiceImpl extends ServiceImpl<AlbumInfoMapper, AlbumInfo> implements AlbumInfoService {

    @Autowired
    private AlbumInfoMapper albumInfoMapper;

    @Autowired
    private AlbumAttributeValueMapper albumAttributeValueMapper;

    @Autowired
    private TrackInfoMapper trackInfoMapper;

    @Autowired
    private TrackStatMapper trackStatMapper;

    @Autowired
    private AlbumStatMapper albumStatMapper;

    @Autowired
    private VodManager vodManager;

    @Autowired
    private KafkaService kafkaService;

    /**
     * 描述：新增专辑
     *
     * @param albumInfoDTO
     * @return
     * @author daiyuling
     * @date 2025/10/24
     */
    @Override
    @Transactional
    public Boolean saveAlbumInfo(Long userId, AlbumSaveOrUpdateDTO albumInfoDTO) {
        // Discount 和 VipDiscount 在0.1-9.9之间 -1表示不折扣
        checkDisCount(albumInfoDTO);
        // 1. 插入专辑信息
        AlbumInfo albumInfo = new AlbumInfo();
        albumInfo.setUserId(userId);

        // 标题审核
        boolean titleCheckPass = !vodManager.checkTextContent(albumInfoDTO.getAlbumTitle());
        if (!titleCheckPass) {
            // 审核不通过，设置状态为审核不通过
            albumInfo.setStatus(SystemConstant.ALBUM_STATUS_NO_PASS);
        } else {
            // 审核通过，设置状态为审核通过
            albumInfo.setStatus(SystemConstant.ALBUM_STATUS_PASS);
        }

        albumInfo.setAlbumTitle(albumInfoDTO.getAlbumTitle());
        albumInfo.setCategory3Id(albumInfoDTO.getCategory3Id());
        // 专辑简介审核
        if (!vodManager.checkTextContent(albumInfoDTO.getAlbumIntro())) {
            albumInfo.setAlbumIntro(albumInfoDTO.getAlbumIntro());
        }
        albumInfo.setCoverUrl(albumInfoDTO.getCoverUrl());
        albumInfo.setEstimatedTrackCount(albumInfoDTO.getEstimatedTrackCount());
        albumInfo.setAlbumRichIntro(albumInfoDTO.getAlbumRichIntro());
        albumInfo.setPayType(albumInfoDTO.getPayType());
        albumInfo.setPriceType(albumInfoDTO.getPriceType());
        albumInfo.setPrice(albumInfoDTO.getPrice());
        albumInfo.setDiscount(albumInfoDTO.getDiscount());
        albumInfo.setVipDiscount(albumInfoDTO.getVipDiscount());
        albumInfo.setTracksForFree(albumInfoDTO.getTracksForFree());
        albumInfo.setBuyNotes(albumInfoDTO.getBuyNotes());
        albumInfo.setSellingPoint(albumInfoDTO.getSellingPoint());
        albumInfo.setIsOpen(albumInfoDTO.getIsOpen());
        // 2. 入库
        this.saveOrUpdate(albumInfo);
        if (!CollectionUtil.isEmpty(albumInfoDTO.getAlbumAttributeValueVoList())) {
            // 2. 添加新的关联关系
            List<AlbumAttributeValueVo> albumAttributeValueVoList = albumInfoDTO.getAlbumAttributeValueVoList();
            List<AlbumAttributeValue> albumAttributeValues = albumAttributeValueVoList.stream()
                    .map(albumAttributeValueVo -> {
                        return albumAttributeValueVo.toAlbumAttributeValue();
                    }).toList();
            albumAttributeValueMapper.insertBatch(albumInfo.getId(), albumAttributeValues);
        }

        // 根据审核结果发送Kafka消息
        if (titleCheckPass) {
            // 审核通过，发送上架消息
            kafkaService.sendMessage(KafkaConst.TOPIC_ALBUM_UPPER, albumInfo.getId());
            log.info("新增专辑审核通过，发送上架消息到Kafka - albumId: {}", albumInfo.getId());
        } else {
            // 审核不通过，发送下架消息
            kafkaService.sendMessage(KafkaConst.TOPIC_ALBUM_LOWER, albumInfo.getId());
            log.info("新增专辑审核不通过，发送下架消息到Kafka - albumId: {}", albumInfo.getId());
        }

        return true;
    }

    /**
     * 描述：根据id查询专辑信息
     *
     * @param id
     * @return
     * @author daiyuling
     * @date 2025/10/27
     */
    @Override
    public AlbumInfoVo getAlbumInfoById(Long id) {
        AlbumInfo albumInfo = this.getById(id);
        AlbumInfoVo albumInfoVo = BeanUtil.copyProperties(albumInfo, AlbumInfoVo.class);
        // 获取AlbumAttributeValueVoList
        List<AlbumAttributeValueVo> albumAttributeValueVoList = albumAttributeValueMapper
                .selectAlbumAttributeValueVoList(id);
        albumInfoVo.setAlbumAttributeValueVoList(albumAttributeValueVoList);
        return albumInfoVo;
    }

    /**
     * 描述：查询用户专辑分页列表
     *
     * @param page
     * @param limit
     * @param albumInfoQuery
     * @return
     * @author daiyuling
     * @date 2025/10/27
     */
    @Override
    public Page<AlbumListVo> findUserAlbumPage(Long page, Long limit, AlbumInfoQuery albumInfoQuery) {
        List<AlbumStatType> albumStatTypes = Arrays.asList(AlbumStatType.values());
        albumInfoQuery.setUserId(AuthContextHolder.getUserId());
        Page<AlbumListVo> pages = new Page<>(page, limit);
        return albumInfoMapper.findUserAlbumPage(pages, albumInfoQuery, albumStatTypes);
    }

    /**
     * 描述：删除专辑信息
     *
     * @param id
     * @return boolean
     * @author daiyuling
     * @date 2025/10/27
     */
    @Override
    @Transactional
    public boolean removeAlbumInfo(Long id) {
        // 删除专辑信息
        boolean remove = this.removeById(id);
        // 删除专辑属性值
        albumAttributeValueMapper.delete(new LambdaQueryWrapper<AlbumAttributeValue>()
                .eq(AlbumAttributeValue::getAlbumId, id));
        // 删除专辑属性
        albumAttributeValueMapper.delete(new LambdaQueryWrapper<AlbumAttributeValue>()
                .eq(AlbumAttributeValue::getAlbumId, id));
        // 删除专辑统计信息
        albumAttributeValueMapper.delete(new LambdaQueryWrapper<AlbumAttributeValue>()
                .eq(AlbumAttributeValue::getAlbumId, id));
        // 发送Kafka消息，异步下架专辑
        kafkaService.sendMessage(KafkaConst.TOPIC_ALBUM_LOWER, id);
        log.info("发送专辑下架消息到Kafka - albumId: {}", id);
        return true;
    }

    /**
     * 描述：修改专辑信息
     *
     * @param id
     * @param albumSaveOrUpdateDTO
     * @author daiyuling
     * @date 2025/10/27
     */
    @Override
    @Transactional
    public void updateAlbumInfo(Long id, AlbumSaveOrUpdateDTO albumSaveOrUpdateDTO) {
        checkDisCount(albumSaveOrUpdateDTO);
        AlbumInfo albumInfo = this.getById(id);
        ThrowUtil.throwIf(albumInfo == null, ResultCodeEnum.DATA_ERROR, "专辑不存在");

        // 保存原状态，用于判断审核状态是否变化
        String oldStatus = albumInfo.getStatus();

        // 专辑 简介&& 标题校验
        boolean titleCheckPass = !vodManager.checkTextContent(albumSaveOrUpdateDTO.getAlbumTitle());
        boolean introCheckPass = !vodManager.checkTextContent(albumSaveOrUpdateDTO.getAlbumIntro());

        // 根据审核结果设置状态
        if (titleCheckPass && introCheckPass) {
            albumInfo.setStatus(SystemConstant.ALBUM_STATUS_PASS);
        } else {
            albumInfo.setStatus(SystemConstant.ALBUM_STATUS_NO_PASS);
            albumSaveOrUpdateDTO.setAlbumIntro(null);
        }

        // 更新专辑表
        BeanUtil.copyProperties(albumSaveOrUpdateDTO, albumInfo);
        ThrowUtil.throwIf(!this.updateById(albumInfo), ResultCodeEnum.SERVICE_ERROR, "更新专辑信息失败");

        // 更新专辑属性表
        // 3. 查询专辑属性值，看是否发生变化
        List<AlbumAttributeValue> oldAttrList = albumAttributeValueMapper.selectList(
                new LambdaQueryWrapper<AlbumAttributeValue>().eq(AlbumAttributeValue::getAlbumId, albumInfo.getId()));
        Set<String> oldSet = new HashSet<>();
        for (AlbumAttributeValue av : oldAttrList) {
            oldSet.add(av.getAttributeId() + ":" + av.getValueId());
        }
        Set<String> newSet = new HashSet<>();
        for (AlbumAttributeValueVo vo : albumSaveOrUpdateDTO.getAlbumAttributeValueVoList()) {
            newSet.add(vo.getAttributeId() + ":" + vo.getValueId());
        }
        boolean isChanged = !CollectionUtil.isEqualList(oldSet, newSet);
        // 4. 如果发生变化，则插入专辑属性值
        if (isChanged) {
            log.info("----------专辑属性值发生变化, 进行修改---------");
            // 1. 先删除所有关联关系
            albumAttributeValueMapper.delete(new LambdaQueryWrapper<AlbumAttributeValue>()
                    .eq(AlbumAttributeValue::getAlbumId, albumInfo.getId()));
            // 2. 添加新的关联关系
            List<AlbumAttributeValueVo> albumAttributeValueVoList = albumSaveOrUpdateDTO.getAlbumAttributeValueVoList();
            List<AlbumAttributeValue> albumAttributeValues = albumAttributeValueVoList.stream()
                    .map(albumAttributeValueVo -> {
                        return albumAttributeValueVo.toAlbumAttributeValue();
                    }).toList();
            albumAttributeValueMapper.insertBatch(albumInfo.getId(), albumAttributeValues);
        }

        // 根据审核状态发送Kafka消息
        String newStatus = albumInfo.getStatus();
        if (SystemConstant.ALBUM_STATUS_PASS.equals(newStatus) && !SystemConstant.ALBUM_STATUS_PASS.equals(oldStatus)) {
            // 状态变为审核通过，发送上架消息
            kafkaService.sendMessage(KafkaConst.TOPIC_ALBUM_UPPER, albumInfo.getId());
            log.info("修改专辑审核通过，发送上架消息到Kafka - albumId: {}", albumInfo.getId());
        } else if (SystemConstant.ALBUM_STATUS_NO_PASS.equals(newStatus)
                && !SystemConstant.ALBUM_STATUS_NO_PASS.equals(oldStatus)) {
            // 状态变为审核不通过，发送下架消息
            kafkaService.sendMessage(KafkaConst.TOPIC_ALBUM_LOWER, albumInfo.getId());
            log.info("修改专辑审核不通过，发送下架消息到Kafka - albumId: {}", albumInfo.getId());
        }
    }

    /**
     * 描述：查询所有专辑分页列表
     *
     * @author daiyuling
     * @date 2025/10/27
     */
    @Override
    public List<AlbumInfoVo> findUserAllAlbumList() {
        Long userId = AuthContextHolder.getUserId();
        return albumInfoMapper.findUserAllAlbumList(userId);
    }

    /**
     * 获取专辑的统计信息
     *
     * @param albumId 专辑ID
     * @return 专辑统计信息
     */
    @Override
    public AlbumStatVo getAlbumStatVo(Long albumId) {
        // 直接从album_stat表查询专辑统计信息
        List<AlbumStatType> albumStatTypes = Arrays.asList(AlbumStatType.values());
        AlbumStatVo albumStatVo = albumStatMapper.getAlbumStatVoByAlbumId(albumId, albumStatTypes);

        // 如果没有统计数据，返回默认值
        if (albumStatVo == null) {
            albumStatVo = new AlbumStatVo();
            albumStatVo.setAlbumId(albumId);
            albumStatVo.setPlayStatNum(0);
            albumStatVo.setSubscribeStatNum(0);
            albumStatVo.setBuyStatNum(0);
            albumStatVo.setCommentStatNum(0);
        }

        return albumStatVo;
    }

    /**
     * 描述：校验折扣
     *
     * @param albumSaveOrUpdateDTO
     * @author daiyuling
     * @date 2025/10/27
     */
    private static void checkDisCount(AlbumSaveOrUpdateDTO albumSaveOrUpdateDTO) {
        // Discount 和 VipDiscount 在0.1-0.99之间 -1表示不折扣
        if (!(albumSaveOrUpdateDTO.getDiscount().compareTo(BigDecimal.valueOf(-1)) == 0)) {
            ThrowUtil.throwIf(
                    (albumSaveOrUpdateDTO.getDiscount().compareTo(BigDecimal.valueOf(0.1)) < 0 ||
                            albumSaveOrUpdateDTO.getDiscount().compareTo(BigDecimal.valueOf(0.99)) > 0),
                    ResultCodeEnum.ILLEGAL_REQUEST,
                    "折扣必须在0.1-0.99之间");
        } else {
            albumSaveOrUpdateDTO.setDiscount(BigDecimal.valueOf(1));
        }
        if (!(albumSaveOrUpdateDTO.getVipDiscount().compareTo(BigDecimal.valueOf(-1)) == 0)) {
            ThrowUtil.throwIf(albumSaveOrUpdateDTO.getVipDiscount().compareTo(BigDecimal.valueOf(0.1)) < 0 ||
                    albumSaveOrUpdateDTO.getVipDiscount().compareTo(BigDecimal.valueOf(0.99)) > 0,
                    ResultCodeEnum.ILLEGAL_REQUEST,
                    "会员折扣必须在0.1-0.99之间");
        } else {
            albumSaveOrUpdateDTO.setVipDiscount(BigDecimal.valueOf(1));
        }
    }
}
